package com.youboy.oauth;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.youboy.oauth.common.OAuthCodec;
import com.youboy.oauth.common.OAuthException;
import com.youboy.oauth.common.OAuthParameters;
import com.youboy.oauth.model.OAuthConsumerAuthentication;
import com.youboy.oauth.token.InvalidTokenException;
import com.youboy.oauth.token.OAuthToken;

/**
 * 
 * @author loudyn
 * 
 */
public class OAuthAccessTokenFilter extends OAuthProcessFilterSupport {

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.youboy.oauth.OAuthProcessFilterSupport#validateOAuthConsumerAuthentication(com.youboy.oauth.model.
	 * OAuthConsumerAuthentication)
	 */
	@Override
	protected void validateOAuthAuthentication(OAuthConsumerAuthentication consumerAuthentication) throws Exception {
		super.validateOAuthAuthentication(consumerAuthentication);

		String requestToken = consumerAuthentication.getOAuthConsumerCredentials().getToken();
		String verifier = consumerAuthentication.getOAuthParameters().get(OAuthParameters.OAUTH_VERIFIER.asString());

		OAuthToken oauthToken = getTokenService().getOAuthToken(requestToken);
		if (null == oauthToken) {
			throw new InvalidTokenException(String.format("the oauthToken(%s) is not exist!", requestToken));
		}

		if (oauthToken.isAccessToken()) {
			throw new InvalidTokenException(String.format("the oauthToken(%s) must not be an accessToken!", requestToken));
		}

		oauthToken.validateVerifier(verifier);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.youboy.oauth.OAuthProcessFilterSupport#onValidOAuthAuthenticate(com.youboy.oauth.model.
	 * OAuthConsumerAuthentication, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse,
	 * javax.servlet.FilterChain)
	 */
	@Override
	protected void onValidOAuthAuthentication(OAuthConsumerAuthentication consumerAuthentication, HttpServletRequest request,
											HttpServletResponse response, FilterChain chain) throws Exception {
		OAuthToken accessToken = createAccessToken(consumerAuthentication.getOAuthConsumerCredentials().getToken());
		if (StringUtils.equals(consumerAuthentication.getOAuthConsumerCredentials().getConsumerKey(), accessToken.getConsumerKey())) {
			throw new OAuthException("the accessToken's consumerKey didn't match consumer'key!");
		}

		renderAccessToken(accessToken, response);
	}

	private void renderAccessToken(OAuthToken accessToken, HttpServletResponse response) throws IOException {

		String responseValue = new StringBuilder().append(OAuthParameters.OAUTH_TOKEN.asString())
													.append("=")
													.append(OAuthCodec.oauthEncode(accessToken.getValue()))
													.append("&")
													.append(OAuthParameters.OAUTH_TOKEN_SECRET.asString())
													.append("=")
													.append(OAuthCodec.oauthEncode(accessToken.getSecret()))
													.toString();

		response.setContentType("text/plain;charset=utf-8");
		response.getWriter().print(responseValue);
		response.flushBuffer();
	}

	private OAuthToken createAccessToken(String token) {
		return getTokenService().createAssessToken(token);
	}
}
